module.exports = {
    createStatementData(invoice, plays) {
        const statementData = {};
        statementData.customer = invoice.customer;
        // map() 方法通过对每个数组元素执行函数来创建新数组。
        statementData.performance = invoice.performance.map(enrichPerformance);
        statementData.totalAmount = totalAmount(statementData);
        statementData.totalVolumeCredits = totalVolumeCredits(statementData);
        return statementData;

        /* 
            返回一个浅副本
            Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上
        */
        function enrichPerformance(aPerformance) {
            // Object.assign(target, source)
            const result = Object.assign({}, aPerformance);
            result.play = playFor(result);
            result.amount = amountFor(result);
            result.volumeCredits = volumeCreditsFor(result);
            return result;
        }

        function playFor(aPerformance) {
            return plays[aPerformance.playID];
        }

        function amountFor(aPerformance) {
            let result = 0;
            switch (aPerformance.play.type) {
                case "tragedy":
                    result = 40000;
                    if (aPerformance.audience > 30) {
                        result += 1000 * (aPerformance.audience - 30);
                    }
                    break;
                case "comedy":
                    result = 3000;
                    if (aPerformance.audience > 20) {
                        result += 1000 + 500 * (aPerformance.audience - 20);
                    }
                    break;
                default:
                    throw new Error("unknown type:" + aPerformance.play.type);
            }
            return result;
        }

        function volumeCreditsFor(aPerformance) {
            let result = 0;
            result += Math.max(aPerformance.audience - 30, 0);
            if ("comedy" === aPerformance.play.type) {
                result += Math.floor(aPerformance.audience / 5);
            }
            return result;
        }

        function totalAmount(data) {
            let result = 0;
            for (let perf of data.performance) {
                result += perf.amount;
            };
            return result;

            // 用管道取代循环
            // return data.performance.reduce((total,p)=>{total+p.amount,0});
        }
        function totalVolumeCredits(data) {
            let result = 0;
            for (let perf of data.performance) {
                result += perf.volumeCredits;
            }
            return result;
            // return data.performance.reduce((total,p)=>{total+p.volumeCredits,0});
        }
    }
}